<?php

/**
 * @作者：linkinghone
 * @所属：PMU团队
 * @日期：2020年4月10日~15日（初代aiMysql）
 * @自由使用（个人或商用都可）和修改
 */

Class aiMysql{

	private function helpString($value){
		if(is_array($value)){

			for ($i=0; $i < count($value); $i++) { 
				if (is_string($value[$i])) {
					$value[$i] = "'".$value[$i]."'";
				}
			}

		}else if (is_string($value)) {
			$value = "'".$value."'";
		}
		return $value;
	}

	private function AND_SIGN_ATTACHING($str,$order){
		if ($order!==0) {
				$str = $str. " AND ";
			}
		return $str;
	}

	private function checkSealed(){
		$sealed = $this->loveSQL["seal"];
		for ($i=0; $i < $max = count($sealed); $i++) { 
			if($sealed[$i] = false){
				$this->dieout("query");
			}
		}
	}

	private function dieout($type){
		switch ($type) {
			case 'param':
				die("<h1>?▂? Required Parameter</h1>");
				break;
			case 'query':
				die("<h1>o(╥﹏╥)o Incomplete Query</h1>");
				break;
			case 'step':
				die("<h1>(╬▔▽▔) Your Step Back is too large</h1>");
				break;
			default:
				# code...
				break;
		}
	}
	private $loveSQLtable;	//SQL的表名
	private $loveSQL;
	private $CachedSQL; //SQL缓存
	private $GOlistener; //监听Go断句

	//断语义连接法词,用法：go(1)或go()
	public function go($step=false){
		//如果已有go
		if ($this-> GOlistener) {
			$this-> loveSQL = $this-> CachedSQL; //将缓存换回
		}else{
			//如果是第一次go
			$this-> GOlistener = true;
			$this-> let_cacheSemantic(); //进行缓存
		}
		if ($step) {
			//重置语义
			$this-> let_resetSemantic($step);
		}else{
			if($step==0){
				$this->let_setupSemantic(); //初始化语义
			}
		}
		return $this;
	}

	public function newgo(){
		$this->let_setupSemantic(); //初始化语义
		return $this;
	}

	protected function let_setupSemantic(){
		$this->loveSQL["midword"] = null;//SQL的中间词
		$this->loveSQL["limit"] = null;//SQL是否带limit
		$this->loveSQL["block"] = null;//记录where
		$this->loveSQL["blockqueue"] = -1;//记录where块的序号
		$this->loveSQL["seal_begin"] = true;//判断seal是否开始
		$this ->loveSQL["seal"] = [true];//判断语义句是否完整的bool数组
		$this-> GOlistener = false; //是否已有断句
	}

	protected function let_resetSemantic($step=false){
		$RESETqueue = $step - 1;
		//超出步长
		if($RESETqueue<-1) $this->dieout("step");
		if ($RESETqueue==-1) {// 返回原位
			$this -> loveSQL["seal"] = [true];
			$this -> loveSQL["seal_begin"] = true;
		}
		
		$this -> loveSQL["seal"] = array_slice($this -> loveSQL["seal"], 0, $step);

		$this->loveSQL["blockqueue"] = $RESETqueue;
		//若回到的where位点的前面直接是错误的，节约后面array_slice的计算
		$this -> loveSQL["block"] = array_slice($this -> loveSQL["block"], 0, $step);
		$this -> loveSQL["midword"] = array_slice($this -> loveSQL["midword"], 0, $step-1);	
	}

	protected function let_cacheSemantic(){
		$this-> CachedSQL = $this-> loveSQL;
	}

	protected function listenBlock($where){
		$this->loveSQL["blockqueue"] += 1;
		//头次的两个操作对应一个序号0，后面的操作是一对一
		if ($this->loveSQL["seal_begin"]) {
			
			$seal_order = 0;
			$this->loveSQL["seal_begin"] = false;
		}else{
			//如果上一个where没关闭，则die
			//这一步在逻辑上禁止任何情景涉及的where没关闭
			if (!$this-> loveSQL["seal"][$this-> loveSQL["blockqueue"]-1]) {
				$this->dieout("query");
			}
			$seal_order = $this-> loveSQL["blockqueue"];
		}
		
		$this-> loveSQL["seal"][$seal_order] = false;
		$this-> loveSQL["block"][$this->loveSQL["blockqueue"]] = $where;
	}

	protected function joinBlock($context,$type){
		$this-> loveSQL["seal"][$this->loveSQL["blockqueue"]] = true;
		if (empty($this-> loveSQL["midword"][$this->loveSQL["blockqueue"]])) {
			$this-> loveSQL["midword"][$this->loveSQL["blockqueue"]] = [];
		}
		array_push($this-> loveSQL["midword"][$this->loveSQL["blockqueue"]],[$type, $context]);
	}

	//指定数据表
	public function table($table){ 
		$this->let_setupSemantic();
		$this->SQLable = $table;
		return $this;
	}

	//指定where
	public function where($where,$value=false){
		$this -> listenBlock($where);
		if ($value) {
			
		}else{
			
		}
		
		return $this;
	}
	//中间词
	public function is($str){
		$this->joinBlock($str,"is");
		return $this;
	}
	//中间词
	public function like($str){
		$this->joinBlock($str,"like");
		return $this;
	}
	//中间词
	public function between($u,$d){
		$this->joinBlock([$u,$d],"between");
		return $this;
	}

	public function limit($start,$end=false){
		$this->loveSQL["limit"] = [$start, $end];
		return $this;
	}

	protected function formSemanticforlimit(){
		$limit 		=	$this->loveSQL["limit"]; 
		if (!empty($limit)) {
			if ($limit[1]) {
				$sql = " LIMIT ".$limit[0].",".$limit[1];
			}else{
				$sql = " LIMIT ".$limit[0];
			}
			return $sql;
		}
		
	}
	protected function formSemanticforwhere($swi,$var){
		$var = $this->helpString($var);
		switch ($swi) {
				case 'is':
					$sql = " = " . $var;
					break;
				case 'like':
					$sql = " LIKE " .$var;
					break;
				case 'between':
					$sql = " BETWEEN ".$var[0] . " AND ".$var[1];
					break;
				default:
					$sql = null;
					break;
			}
		return $sql;
	}
		
	//Where整体加入SQL
	protected function WhereSQL($sql){
		//如果语义最后一个where没被中间词（伪中间词）关闭，则die
		//$this-> checkSealed();也可以，不过需要遍历数组且对比，比直接取最后一个慢
		if (!end($this->loveSQL["seal"])) {
			$this->dieout("query");
		}
		$queue 		= 	$this->loveSQL["blockqueue"];
		$listener 	=	$this->loveSQL["block"];
		$lover 		= 	$this->loveSQL["midword"];
		
		if ($this->loveSQL["blockqueue"]>=0) {
			$sql = $sql." WHERE ";
		}

		for ($i=0; $i < $queue +1 ; $i++) { 
			if (!$lover[$i][0][0]) {
			//如果lover对象是write一类的尾词（作伪中间词），不必新增where语句
				return $sql;
			}

			$sql = $this->AND_SIGN_ATTACHING($sql,$i);
			$sql = $sql.$listener[$i];

				for ($j=0; $j <count($lover[$i]) ; $j++) { 

					$sql = $this->AND_SIGN_ATTACHING($sql,$j);
					$sql = $sql.$this->formSemanticforwhere($lover[$i][$j][0],$lover[$i][$j][1]);
				}
			
		}

		$sql = $sql.$this->formSemanticforlimit();
		return $sql;
	}

	//查找
	public function find(){

		$sql = "SELECT * FROM ".$this->SQLable;
		$sql = $this-> WhereSQL($sql);

		return $sql;

		if (!empty($this->handover($this->ServerIn,$sql))) {
			return mysqli_fetch_all($this->handover($this->ServerIn,$sql));
		}else{
			return null;
		}
	}
	//写入（包括新增和更新内容）
	public function write($up,$down=false){
		//没有where语句时
		if ($this->loveSQL["blockqueue"]<0) {
			//此刻若程序员马虎没输入数组，报false
			if (is_array($up)) {
				$dataline = $up;
				$column_all = null;
				$data_all = null;
				//批次将数组写入String
				foreach ($dataline as $key => $value) {
					$column_all =  $column_all . $key. ",";
					$data_all = $data_all .$this->helpString($value). ",";
				}
				$sql = "INSERT INTO ". $this->SQLable;
				$sql = $sql . "(".rtrim($column_all,",").")";
				$sql = $sql . " VALUES (".rtrim($data_all,",").")";
			}else{
				return false;
			}
		}else{
			//指定where
			//输入数组，进行数组更新。否则按两个变量更新。
			if (is_array($up)) {
				$SET = null;
				//批次将数组写入String
				foreach ($up as $key => $value) {
					$SET = $SET.$key ." = ".$this-> helpString($value).",";
				}
				$SET = rtrim($SET,",");
			}else{

				//如果采取语义写法
				if (!$down) {

					//如果语义完整，说明不是语义写法，抛错
					if($this->loveSQL["seal"][$this->loveSQL["blockqueue"]]) $this->dieout("param");

					//加入语义
					$this->joinBlock(false,false); //假中间词

					$down = $up;

					$up = $this->loveSQL["block"][$this->loveSQL["blockqueue"]];
				}
				$SET = $up." = ".$this->helpString($down);
			}
			$sql = "UPDATE ". $this->SQLable." SET ".$SET;
			$sql = $this->WhereSQL($sql);
		}
		return $sql;
		return $this->handover($this->ServerIn,$sql);
	}

	public function delete(){
		#构造基本语法
		$sql = "DELETE FROM ".$this->SQLable;
		#添加所有where定位的后缀
		$sql = $this->WhereSQL($sql);
		#将sql交给handover
		$this->handover($this->ServerIn,$sql);
	}

	//新建表
	public function maketable($table){
		return true;
	}
	
	//删除表
	public function deletetable($table){
		return true;
	}

	//更换数据库
	public function switchServer($serverIn){
		$this->underneathload($serverIn);
		return $this;
	}

	//数据库连接信息
	private $ServerIn;

	//载入默认数据库配置
	function __construct(){
		include_once "config.php";
		$config = new config();
   		$this -> underneathload(
   			$config->configDB_load()
   		);
	}
	//写入config
	protected function underneathload($config){
		for ($i=0; $i < 4; $i++) { 
			$this -> ServerIn[$i] = $config[$i];
		}
	}

	//只进行SQL查询
   	protected function handover($serverIn,$sql){
  		$conn = new mysqli($serverIn[0],
  			$serverIn[1],
  			$serverIn[2],
  			$serverIn[3]
  		);
  		//每一步错误/成功连接都被关闭
 		if($conn -> connect_error){
 			mysqli_close($conn);
 			return false;
 		}
 		if(!$result = $conn-> query($sql)) {
 			mysqli_close($conn);
 			return false;
 		}
 		mysqli_close($conn);
 		return $result;
  	}

 }
?>